/**
 * 
 */
package org.oy.sealogger.parser;

import java.util.Observable;

import org.oy.sealogger.logger.XMLTags;

/**
 * @author juho
 *
 */
public class RMCSentence extends NMEA0183Sentence {

	/**
	 * RMC  = Recommended Minimum Specific GPS/TRANSIT Data

		1    = UTC of position fix
		2    = Data status (V=navigation receiver warning)
		3    = Latitude of fix
		4    = N or S
		5    = Longitude of fix
		6    = E or W
		7    = Speed over ground in knots
		8    = Track made good in degrees True
		9    = UT date
		10   = Magnetic variation degrees (Easterly var. subtracts from true course)
		11   = E or W
		12   = Checksum
	 * @param gpsdata
	 */
	
	private static final int TIME = 1;
	private static final int STATUS = 2;
	private static final int LATITUDE = 3;
	private static final int LATITUDEDIR = 4;
	private static final int LONGITUDE = 5;
	private static final int LONGITUDEDIR = 6;
	private static final int SPEED = 7;
	private static final int TRACK = 8;
	private static final int DATE = 9;
	private static final int MAGVARIANCE = 10;
	private static final int MAGVARIANCEDIR = 11;
	private static final int CHECKSUM = 12;
	
	public RMCSentence(String sentence) {
		super(sentence);
		// TODO Auto-generated constructor stub
	}
	
	public RMCSentence() {
		// TODO Auto-generated constructor stub
	}

	public double getTrack() {
		if(dataFields == null || dataFields[TRACK] == null) {
			return 0.0;
		}
		return new Double(dataFields[TRACK]).doubleValue();
	}
	
	public String getTime() {
		if (dataFields == null || dataFields[TIME] == null) {
			return "0";
		}
		return dataFields[TIME];
	}

	public String getLatitude() {
		int delim = 0;
		if (dataFields == null || dataFields[LATITUDE] == null) {
			return "0";
		}

		String latitude = dataFields[LATITUDE];
		if (latitude.indexOf(".") == 5) {
			delim = 3;
		} else {
			delim = 2;
		}
		String latitudeDegrees = latitude.substring(0, delim);
		String latitudeMinutes = latitude.substring(delim, latitude.length());
		latitude = latitudeDegrees + "\u00B0 " + latitudeMinutes + "\' " + " " + getLatitudeDirection();

		return latitude;
	}
	
	public String getLatitudeDirection() {
		if (dataFields == null || dataFields[LATITUDEDIR] == null) {
			return "0";
		}
		return dataFields[LATITUDEDIR];
	}

	public String getLongitude() {
		int delim = 0;
		if (dataFields == null || dataFields[LONGITUDE] == null) {
			return "0";
		}

		String longitude = dataFields[LONGITUDE];
		if (longitude.indexOf(".") == 5) {
			delim = 3;
		} else {
			delim = 2;
		}
		String longitudeDegrees = longitude.substring(0, delim);
		String longitudeMinutes = longitude.substring(delim, longitude.length());
		longitude = longitudeDegrees + "\u00B0 " + longitudeMinutes + "\' " + " " + getLongitudeDirection();
		
		if (longitude.charAt(0) == '0') {
			longitude = longitude.substring(1, longitude.length());
		}
		
		return longitude;
	}
	
	public String getLongitudeDirection() {
		if (dataFields == null || dataFields[LONGITUDEDIR] == null) {
			return "0";
		}
		return dataFields[LONGITUDEDIR];
	}
	

	public void addSentence(String newSentence) {
		if (sentence == null ) {
			sentence = newSentence;
		} else {
			//tests if anything else other than time or checksum has changed.
			//if (!sentence.substring(13, sentence.length()-3).equals(newSentence.substring(13, sentence.length()-3))) {
			
				sentence = newSentence;
				dataFields = newSentence.split(delim);
				setChanged();
				notifyObservers();
			//}
			
			
		}
		
	}
	
	public double getLongitudeAsDouble() {
		double lon = 0;
		
		if (dataFields == null || dataFields[LONGITUDE] == null) {
			return 0;
		}
		
		// convert longitude
		String longitude = dataFields[LONGITUDE];
		//degrees are the 3 first numbers
		double deg = Double.valueOf(longitude.substring(0, 3));
		double min = Double.valueOf(longitude.substring(3, longitude.length()));
		// NMEA longitude format can be converted to decimal format by
		// dividing minutes by 60
		lon = deg + min/60;
		
		// if longitude direction is W it's marked negative
		if (dataFields[LONGITUDEDIR].equals("W")) {
			lon = lon * -1;
		}
		
		return lon;
	}
	
	public double getLatitudeAsDouble() {
		double lat = 0;
		
		if (dataFields == null || dataFields[LATITUDE] == null || dataFields[LATITUDEDIR] == null ) {
			return 0;
		}
		// convert longitude
		String latitude = dataFields[LATITUDE];
		// degrees are the 2 first numbers
		double deg = Double.valueOf(latitude.substring(0, 2));
		double min = Double.valueOf(latitude.substring(2, latitude.length()));
		// NMEA latitude format can be converted to decimal format by
		// dividing minutes by 60
		lat = deg + min/60;
		
		// if latitude is south it's marked negative
		if (dataFields[LATITUDEDIR].equals("S")) {
			lat = lat * -1;
		}
		
		return lat;
	}
	
	public double getSpeed() {
		if (dataFields == null || dataFields[SPEED] == null) {
			return 0;
		}
		return Double.parseDouble(dataFields[SPEED]);
	}

	
	public String getXMLSentence() {
		return "<RMCSentence>" + sentence + "</RMCSentence>";
	}
	
	public String getLocationXML() {
		
		if (dataFields == null || dataFields[LONGITUDE] == null || dataFields[LONGITUDEDIR] == null || dataFields[LATITUDE] == null || dataFields[LATITUDEDIR] == null)
		{
			return null;
		}
		
		String xml = "";
		xml += "<"+XMLTags.LOCATION_TAG+">\n";
		xml += "\t<"+XMLTags.LONGITUDE_TAG+">" + getLongitudeAsDouble() + "</"+XMLTags.LONGITUDE_TAG+">\n";
		xml += "\t<"+XMLTags.LATITUDE_TAG+">" + getLatitudeAsDouble() + "</"+XMLTags.LATITUDE_TAG+">\n";
		xml += "</"+XMLTags.LOCATION_TAG+">";
		return xml;
	}

	public void update(Observable dataSource, Object rawData) {
		addSentence((String)rawData);

	}
}
